package com.jcodes.simple.config;

import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.jcodes.simple.common.base.R;

import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {


    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler
    public R<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        List<ObjectError> allErrors = bindingResult.getAllErrors();
        String msg = allErrors.stream().map(item -> {
            if (item instanceof FieldError fieldError) {
                return "[" + fieldError.getField() + "]" + item.getDefaultMessage();
            } else {
                return "[" + item.getObjectName() + "]" + item.getDefaultMessage();
            }
        }).collect(Collectors.joining(";"));
        logException(msg, e);
        return R.err("参数校验失败:" + msg);
    }

    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public R<?> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        logException("请求内容不可读", e);
        return R.err("请求内容不可读");
    }

    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler
    public R<?> handleException(Exception e) {
        logException("发生未知错误", e);
        return R.err("发生未知错误");
    }

    private void logException(String msg, Exception e) {
        log.error(msg, e);
    }
}
